<?php

namespace brand\traits;
use brand\build\Columns;
use brand\logic\BrandHelper;
use brand\logic\Config;
use brand\logic\PageCurd;
use brand\page\Form;
use brand\page\Page;
use brand\page\Table;
use brand\tools\Functions;
use think\facade\Db;
use think\facade\View;
use function _error;
use function _success;


trait BrandAdmin
{
    protected $form;
    protected $table;

    public static $curdConfig;

    //curd名称
    protected $curdName = "";
    protected $pk = '';

    use BrandEvent;

    //初始化curd
    public function init_curd()
    {
        Config::FactoryConfig();


        $this->curdName = $this->curdName ?: BrandHelper::getCurdNameByControllerName($this->request->controller());

        Page::$curdConfig = self::$curdConfig = BrandHelper::getCurdConfigByName($this->curdName);
        Page::setConfig(self::$curdConfig['page'] ?? []);
        PageCurd::$curdName = $this->curdName;

        $this->_setColumns();
        Table::init($this->curdName);
        Form::init($this->curdName);



    }


    /**
     * Table列表页显示
     */
    public function index()
    {

        BrandHelper::checkCurdName($this->curdName);
        if ($this->request->isAjax() || $this->request->post()){
            return $this->_tabledata();
        }

        Table::$pk = $this->getPk();

        $this->table_init();

        //设置头信息
        Table::$SurfaceTable->header(Table::header());

        //获取行数据
        $table_column = $this->table_after_set_columns(Columns::getConfig());
        $columns = $this->table_after_build(Table::buildTable($table_column));


        //设置行数据
        Table::$SurfaceTable->columns($columns);

        //设置搜索
        $this->table_search_before_build();

        //搜索默认值
        $this->table_search_raws();
        $search_columns = $this->table_search_after_build(Form::builderSearch(Columns::getConfig(),Form::$searchRaw));
        Table::$SurfaceTable->search($search_columns);
        //设置分页
        Table::$SurfaceTable->pagination( Table::pagination());
        //显示页面
        return Table::$SurfaceTable->view();
    }


    /**
     * 获取表结构
     */
    public function _setColumns()
    {
        Columns::setConfig(
            BrandHelper::getCurdConfigByName($this->curdName)['columns'] ?? []
        );
    }

    /**
     * 新增
     */
    public function add()
    {
        Form::$action = 'add';
        //新增操作
        if ($this->request->isAjax()){
            return $this->submitFrom();
        }
        return $this->edit(true);
    }

    /**
     * 修改
     */
    public function edit($add = false)
    {
        Form::$action = $add ? 'add' : 'edit';
        //列表单独更新
        if ($this->request->isAjax() && $this->request->get('brand_update')){
            return $this->update();
        }
        //修改页面提交
        if ($this->request->isAjax()){
            return $this->submitFrom();
        }


        $this->form_init();

        //查询数据
        $raw = $this->getDb()->where( $this->getPk() , $this->request->param( $this->getPk() ) )->find();
        if($raw && is_object($raw)) $raw = $raw->toArray();
        if (!$raw) $raw = [];
        $raw = array_merge($raw,$this->request->param());

        if (!$add && !$raw) {
            $this->error('暂无数据');
        };

        //排序
        if(!isset($raw['weigh']) && Columns::getColumn('weigh')){
            $raw['weigh'] = ($this->getDb()->order($this->getPk().' desc')->value($this->getPk()) ?: 0) + 1;
        }
        //状态
        if (!isset($raw['status']) && Columns::getColumn('status') && $add){
            $raw['status'] = 1;
        }

        $raw = $this->form_before_build($raw);
        //构造Form表单
        $columns_arr = Form::buildForm(Columns::getConfig(),$raw);
        $columns_arr = $this->form_after_build($columns_arr);

        Form::buildColumns($columns_arr);

        return Form::buildView();
    }

    /**
     * 新增和修改提交表单
     */
    public function submitFrom()
    {


        //获取字段
        $params = BrandHelper::submitCharField($this->curdName);
        $params = $this->submit_before_params($params);

        Db::startTrans();
        try {


            $this->_toSave($params);

            Db::commit();
            return _success('操作成功');
        }catch (\Exception $exception){
            Db::rollback();
            return _error($exception->getMessage());
        }



    }

    /**
     * 保存数据
     * @param $params
     */
    public function _toSave($params)
    {
        $params = $this->submit_save_before($params);
        if (isset($params[$this->getPk()]) && $params[$this->getPk()]){
            $this->getDb()->strict(false)->update($params);
            $id = $params[$this->getPk()];
        }else{
            $id = $this->getDb()->strict(false)->insertGetId($params);
        }

        $this->submit_save_after($params,$id);

    }



    /**
     * 表格数据搜索
     */
    public function _tableData( )
    {
        //构建搜索条件
        PageCurd::buildSelectCondition($this->getPk());
        //JOIN
        PageCurd::buildJoin();
        $table = BrandHelper::getTableNameByName($this->curdName);
        $this->data_before_search();
        $data = $this->getDb()->alias($this->curdName)->where(PageCurd::$conditionWhere);


        foreach (PageCurd::$joinArray as $join) {
            $data = $data->join($join['join'],$join['condition'],$join['type']);
        }

        //查询字段
        $data = $data->field(PageCurd::$joinFields);

        //排序
        if (PageCurd::$conditionSortField && PageCurd::$conditionSortOrder){
            $data = $data->order( PageCurd::$conditionSortField.' ' .PageCurd::$conditionSortOrder);
        }
        //分页
        if (PageCurd::$conditionLimit > 0){
            $data = $data->paginate(PageCurd::$conditionLimit);
            $list = $data->all();
            $count = $data->total();
        }else{
            $list = $data->select();
            $count = count($list);
        }

        $list = $this->data_before_select($list);
        //格式化特殊字段
        $list = PageCurd::specialField($list);

        [$count,$list] = $this->data_after_select($count,$list);

        //统计
        $stat = PageCurd::buildStat($this->getDb(),Config::$stat_html);

        //返回数据
//        $res = ['count'=>$count,'list'=>$list,'stat'=>$stat];
        $res = ['total'=>$count,'items'=>$list,'count'=>$count,'list'=>$list,'stat'=>$stat];
        if (Config::$is_async){
            return _success('',$res);
        }else{
            return  $res;
        }
    }



    /**
     * 列表更新
     */
    public function update()
    {
        $pk = $this->getPk();
        $id = $this->request->param($pk);

        $value = $this->request->param('value');
        $field = $this->request->param('field');


        if (strstr($field,'__BA__')){
            return _error('关联表不支持修改');
        }

        if (is_array($value)) $value = json_encode($value);

        [$field,$value,$pk,$id] = $this->table_before_update_field($field,$value,$pk,$id);
        $this->getDb()->where([$pk=>$id])->save([$field=>$value]);
        $this->table_before_after_field($field,$value,$pk,$id);

        return _success();
    }

    /**
     * 删除
     */
    public function del()
    {
        $pk = $this->getPk();
        $id = $this->request->post($pk);
        if(!$id) return _error('参数错误');
        if (!is_array($id)){
            $id = [$id];
        }
        [$pk,$id] = $this->delete_before($this->curdName,$pk,$id);

        //判断软删除
        $soft_delete = BrandHelper::SoftDelete(Columns::getConfig());

        if ($soft_delete){
            $res = $this->getDb()->whereIn($pk,$id)->update($soft_delete);
        }else{
            $res = $this->getDb()->whereIn($pk,$id)->delete();
        }

        if ($res){
            $this->delete_after($this->curdName,$pk,$id);
            return _success('操作成功');
        }
        return _error('操作失败');
    }






    /**
     * 导出功能
     */
    public function export()
    {

        $config = BrandHelper::getCurdConfigByName($this->curdName);
        $columns = Columns::getConfig();

        Config::$page_limit = 0;
        Config::$is_async = false;
        Config::$stat_html = 0;

        $res =  $this->_tableData();

        $resList = [];

        //有没有统计
        $stat = $res['stat'] ?? [];
        $statData = [];
        if ($stat){
            $statData[] = '统计：';
            foreach ($stat as $item) {
                $statData[] = $item['title'].'：'.$item['value'];
            }
            $resList[] = $statData;
        }


        $list = $res['list'] ?? [];
        if (is_object($list)) $list = $list->toArray();

        $titles = [];
        $titles_keys = [];

        foreach ($columns as $key => $item) {
            if (Table::columnsTableIsShow($item)){
                $titles[] = $item['title'] ?? $key;
                $titles_keys[] =  $key;
            }
        }


        $resList[] = $titles;
        foreach ($list as $item) {
            $arr = [];
            foreach ($titles_keys as  $value) {
                $arr[] = $item[$value] ?? '';
            }
            $resList[] = $arr;
        }


        return _success('',['title'=>$config['title'] ?? "",'list'=>$resList]);

    }

    /**
     * 获取主键
     */
    public function getPk()
    {
        return $this->pk ?: BrandHelper::getPkByName($this->curdName);
    }
    /**
     * 获取Db对象
     * @param $name
     * @return Db
     */
    public function getDb($name = "")
    {
        if (!$name) $name = $this->curdName;
        $name  = BrandHelper::getTableNameByName($name);
        $name = $this->db_name_before($name);
        $db = Db::name($name);
        $model = str_replace('\\admin\controller\\', '\\common\model\\', get_class($this));
        if (class_exists($model)){
            $db =  new $model();
        }
        return $this->db_reset($db);
    }

}